package co.fitstart.admin.web.controller.user;

import java.util.Date;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;

import com.demo2do.core.support.Page;
import com.demo2do.core.support.Result;
import com.demo2do.core.utils.DateFormatUtils;
import com.demo2do.core.utils.JsonUtils;
import com.demo2do.core.web.resolver.Preloading;
import com.demo2do.core.web.utils.WebUtils;

import co.fitstart.admin.entity.search.TelephoneRecordSearch;
import co.fitstart.admin.entity.search.TelephoneResourceSearch;
import co.fitstart.admin.entity.security.Login;
import co.fitstart.admin.service.CourseScheduleService;
import co.fitstart.admin.service.PrincipalService;
import co.fitstart.admin.service.SiteService;
import co.fitstart.admin.service.TelephoneResourceService;
import co.fitstart.admin.web.interceptor.MenuSetting;
import co.fitstart.admin.web.resolver.Secure;
import co.fitstart.admin.web.view.ExcelTemplateView;
import co.fitstart.entity.course.schedule.CourseSchedule;
import co.fitstart.entity.principal.Principal;
import co.fitstart.entity.reference.Gender;
import co.fitstart.entity.site.Site;
import co.fitstart.entity.user.TelephoneRecord;
import co.fitstart.entity.user.TelephoneResource;
import co.fitstart.entity.user.User;

/**
 * 电话资源
 * @author haiyan_xiao
 *
 */
@Controller
@RequestMapping("/telephone-resources")
@MenuSetting("menu-user")
public class TelephoneResourceController {
    
    private static final Logger logger = LoggerFactory.getLogger(TelephoneResourceController.class);
    
    @Autowired
    private TelephoneResourceService telephoneResourceService;
    
    @Autowired
    private PrincipalService principalService;
    
    @Autowired
    private CourseScheduleService courseScheduleService;
    
    @Autowired
    private SiteService siteService;
    
    /**
     * 
     * @param page
     * @param request
     * @return
     */
    @RequestMapping(value = "", method = RequestMethod.GET)
    @MenuSetting("submenu-telephone-resource-management")
    public ModelAndView list(@RequestParam(value = "period", required = false, defaultValue="week") String period,
                             @RequestParam(value = "date", required = false) @DateTimeFormat(pattern = "yyyy-MM-dd") Date day,
                             @RequestParam(value = "experienced", required = false) Boolean experienced,
                             Page page,
                             HttpServletRequest request) {
        ModelAndView modelAndView = new ModelAndView("user/telephone/telephone-resource-list");
        
        if(day == null) {
            day = new Date();
        }
        
        List<TelephoneResource> telephoneResources = telephoneResourceService.list(period, day, experienced, page);
        int total = telephoneResourceService.count(period, day, experienced);
        
        modelAndView.addObject("telephoneResources", telephoneResources);
        modelAndView.addObject("total", total);
        
        modelAndView.addObject("period", period);
        modelAndView.addObject("day", DateFormatUtils.format(day, "yyyy-MM-dd"));
        modelAndView.addObject("experienced", experienced);
        Map<String, Date> times = telephoneResourceService.getTimes(day, period);
        if(!times.isEmpty()) {
            modelAndView.addObject("begin", DateFormatUtils.format(times.get("begin"), "yyyy-MM-dd"));
            modelAndView.addObject("end", DateFormatUtils.format(times.get("end"), "yyyy-MM-dd"));
        }
        modelAndView.addObject("today", DateFormatUtils.format(new Date(), "yyyy-MM-dd"));
        modelAndView.addObject("page", page);
        modelAndView.addObject("queryString", WebUtils.extractQueryString(request, "page"));
        
        return modelAndView;
    }
    
    /**
     * 
     * @return
     */
    @RequestMapping(value = "/create", method = RequestMethod.GET)
    public ModelAndView create(){
        
        ModelAndView modelAndView = new ModelAndView("user/telephone/telephone-resource-create");
        
        return modelAndView;
    }
    
    /**
     * 
     * @param mobile
     * @param gender
     * @param name
     * @param telephoneResource
     * @return
     */
    @RequestMapping(value = "", method = RequestMethod.POST)
    public @ResponseBody String onCreate(@RequestParam("mobile") String mobile,
                                         @RequestParam("gender") Gender gender,
                                         @RequestParam("name") String name,
                                         TelephoneResource telephoneResource){
        
        Result result = new Result();
        
        try {
            telephoneResourceService.create(mobile, gender, name, telephoneResource);
            
            result.success().message("添加电话资源成功！");
        } catch(Exception e) {
            logger.error("TelephoneResourceController#onCreate - ", e);
            result.fail().message("添加电话资源失败！");
        }
        
        return JsonUtils.toJsonString(result);
    }
    
    /**
     * 
     * @param telephoneResourceId
     * @return
     */
    @RequestMapping(value = "/{telephoneResourceId}", method = RequestMethod.GET)
    @MenuSetting("submenu-telephone-resource-management")
    public ModelAndView view(@PathVariable("telephoneResourceId") Long telephoneResourceId){
        ModelAndView modelAndView = new ModelAndView("user/telephone/telephone-resource-view");
        
        TelephoneResource telephoneResource = telephoneResourceService.load(telephoneResourceId);
        
        modelAndView.addObject("telephoneResource", telephoneResource);
        
        return modelAndView;
    }
    
    /**
     * 
     * @param telephoneResourceId
     * @return
     */
    @RequestMapping(value = "/{telephoneResourceId}/edit", method = RequestMethod.GET)
    public ModelAndView edit(@PathVariable("telephoneResourceId") Long telephoneResourceId){
        ModelAndView modelAndView = new ModelAndView("user/telephone/telephone-resource-edit");
        
        TelephoneResource telephoneResource = telephoneResourceService.load(telephoneResourceId);
        
        modelAndView.addObject("telephoneResource", telephoneResource);
        
        return modelAndView;
    }
    
    /**
     * 
     * @param collectDate
     * @param telephoneResource
     * @return
     */
    @RequestMapping(value = "/{telephoneResourceId}/edit", method = RequestMethod.PATCH)
    public @ResponseBody String onEdit(@Preloading("id") TelephoneResource telephoneResource){
        
        Result result = new Result();
        
        try {
            telephoneResourceService.update(telephoneResource);
            
            result.success().message("修改电话资源成功！");
        } catch(Exception e) {
            logger.error("TelephoneResourceController#onEdit - ", e);
            result.fail().message("修改电话资源失败！");
        }
        
        return JsonUtils.toJsonString(result);
    }
    
    /**
     * 
     * @param telephoneResourceId
     * @return
     */
    @RequestMapping(value = "/{telephoneResourceId}/edit-break-reason", method = RequestMethod.GET)
    public ModelAndView editBreakReason(@PathVariable("telephoneResourceId") Long telephoneResourceId){
        ModelAndView modelAndView = new ModelAndView("user/telephone/break-reason-edit");
        
        TelephoneResource telephoneResource = telephoneResourceService.load(telephoneResourceId);
        
        modelAndView.addObject("telephoneResource", telephoneResource);
        
        return modelAndView;
    }
    
    /**
     * 
     * @param telephoneResourceId
     * @param reason
     * @return
     */
    @RequestMapping(value = "/{telephoneResourceId}/break-reason", method = RequestMethod.PATCH)
    public @ResponseBody String onEditBreakReason(@PathVariable("telephoneResourceId") Long telephoneResourceId,
                                                  @RequestParam("reason") String reason){
        
        Result result = new Result();
        
        try {
            TelephoneResource telephoneResource = telephoneResourceService.load(telephoneResourceId);
            
            telephoneResourceService.update(telephoneResource.editBreakReason(reason));
            
            result.success().message("修改未到店原因成功！");
        } catch(Exception e) {
            logger.error("TelephoneResourceController#onEditBreakReason - ", e);
            result.fail().message("修改未到店原因失败！");
        }
        
        return JsonUtils.toJsonString(result);
    }
    
    /**
     * 
     * @param telephoneResourceId
     * @return
     */
    @RequestMapping(value = "/{telephoneResourceId}/telephone-records/add", method = RequestMethod.GET)
    public ModelAndView addTelephoneRecord(@PathVariable("telephoneResourceId") Long telephoneResourceId){
        ModelAndView modelAndView = new ModelAndView("user/telephone/telephone-record-create");
        
        TelephoneResource telephoneResource = telephoneResourceService.load(telephoneResourceId);
        
        modelAndView.addObject("telephoneResource", telephoneResource);
        
        return modelAndView;
    }
    
    /**
     * 
     * @param login
     * @param telephoneResourceId
     * @param telephoneRecord
     * @return
     */
    @RequestMapping(value = "/{telephoneResourceId}/telephone-records", method = RequestMethod.POST)
    public @ResponseBody String onAddTelephoneRecord(@Secure Login login,
                                                     @PathVariable("telephoneResourceId") Long telephoneResourceId,
                                                     TelephoneRecord telephoneRecord){
        
        Result result = new Result();
        
        try {
            TelephoneResource telephoneResource = telephoneResourceService.load(telephoneResourceId);
            Principal principal = principalService.load(Principal.class, login.getId());
            
            telephoneResourceService.addTelephoneRecord(telephoneRecord.editTelephoneResource(telephoneResource).editReceptionist(principal));
            
            result.success().message("添加电话接待记录成功！");
        } catch(Exception e) {
            logger.error("TelephoneResourceController#onAddTelephoneRecord - ", e);
            result.fail().message("添加电话接待记录失败！");
        }
        
        return JsonUtils.toJsonString(result);
    }
    
    /**
     * 
     * @param telephoneResourceId
     * @param telephoneRecordId
     * @return
     */
    @RequestMapping(value = "/{telephoneResourceId}/telephone-records/{telephoneRecordId}/edit", method = RequestMethod.GET)
    public ModelAndView editTelephoneRecord(@PathVariable("telephoneResourceId") Long telephoneResourceId,
                                           @PathVariable("telephoneRecordId") Long telephoneRecordId){
        ModelAndView modelAndView = new ModelAndView("user/telephone/telephone-record-edit");
        
        TelephoneRecord telephoneRecord = telephoneResourceService.loadTelephoneRecord(telephoneRecordId);
        
        modelAndView.addObject("telephoneRecord", telephoneRecord);
        
        return modelAndView;
    }
    
    /**
     * 
     * @param login
     * @param telephoneRecord
     * @return
     */
    @RequestMapping(value = "/{telephoneResourceId}/telephone-records/{telephoneRecordId}", method = RequestMethod.PATCH)
    public @ResponseBody String onEditTelephoneRecord(@Secure Login login,
                                                      @Preloading("id") TelephoneRecord telephoneRecord){
        
        Result result = new Result();
        
        try {
            telephoneResourceService.updateTelephoneRecord(telephoneRecord);
            
            result.success().message("修改电话接待记录成功！");
        } catch(Exception e) {
            logger.error("TelephoneResourceController#onEditTelephoneRecord - ", e);
            result.fail().message("修改电话接待记录失败！");
        }
        
        return JsonUtils.toJsonString(result);
    }
    
    /**
     * 
     * @return
     */
    @RequestMapping(value = "/export-view", method = RequestMethod.GET)
    public ModelAndView export(){
        ModelAndView modelAndView = new ModelAndView("user/telephone/telephone-resource-export");
        
        modelAndView.addObject("today", DateFormatUtils.format(new Date(), "yyyy-MM-dd"));
        
        return modelAndView;
    }
    
    @RequestMapping(value = "/export", method = RequestMethod.GET)
    public ModelAndView onExport(@Secure Login login,
                                 @RequestParam(value = "siteId", required = false) Long siteId,
                                 @RequestParam(value = "receptionistId", required = false) Long receptionistId,
                                 TelephoneResourceSearch search){
        ModelAndView modelAndView = new ModelAndView(new ExcelTemplateView("telephone-resource-report.xls"));
        
        Site site = null;
        if(login.hasSite()) {
            site = login.getSite();
        } else if(siteId != null) {
            site = siteService.load(siteId);
        }
        
        if(site == null) {
            if(login.isAreaManager() || login.isAreaServer()) {
                Principal principal = principalService.load(Principal.class, login.getId());
                search.setSites(siteService.listSite(principal));
            }
        } else {
            search.setSite(site);
        }
        
        Principal receptionist = null;
        if(receptionistId != null) {
            receptionist = principalService.load(Principal.class, receptionistId);
        }
        search.setReceptionist(receptionist);
        
        List<TelephoneResource> telephoneResources = telephoneResourceService.search(search);
        
        TelephoneRecordSearch telephoneRecordSearch = new TelephoneRecordSearch(search);
        
        Map<Long, Long> recordCounts = telephoneResourceService.listTelephoneRecordCount(telephoneRecordSearch);
        
        List<User> users = telephoneResourceService.listUser(search);
        if(!users.isEmpty()) {
            Map<Long, CourseSchedule> schedules = telephoneResourceService.listSchedule(users);
            Map<Long, Long> roundCounts = telephoneResourceService.listRoundCount(users);
            Map<Long, Long> roundPriceSums = telephoneResourceService.listRoundPriceSum(users);
            
            modelAndView.addObject("schedules", schedules);
            modelAndView.addObject("roundCounts", roundCounts);
            modelAndView.addObject("roundPriceSums", roundPriceSums);
        }
        
        modelAndView.addObject("telephoneResources", telephoneResources);
        modelAndView.addObject("recordCounts", recordCounts);
        modelAndView.addObject("site", site);
        modelAndView.addObject("receptionist", receptionist);
        modelAndView.addObject("experienced", search.getExperienced());
        modelAndView.addObject("begin", DateFormatUtils.format(search.getBegin(), "yyyy-MM-dd"));
        modelAndView.addObject("end", DateFormatUtils.format(search.getEnd(), "yyyy-MM-dd"));
        
        return modelAndView;
    }
    
    @RequestMapping(value = "/{telephoneResourceId}/add-experience", method = RequestMethod.GET)
    public ModelAndView addExperience(@PathVariable("telephoneResourceId") Long telephoneResourceId){
        ModelAndView modelAndView = new ModelAndView("user/telephone/experience-add");
        
        TelephoneResource telephoneResource = telephoneResourceService.load(telephoneResourceId);
        
        modelAndView.addObject("user", telephoneResource.getUser());
        
        return modelAndView;
    }
    
    /**
     * edit experience
     * @param telephoneResourceId
     * @param courseScheduleId
     * @return
     */
    @RequestMapping(value = "/{telephoneResourceId}/edit-experience", method = RequestMethod.GET)
    public ModelAndView editExperience(@PathVariable("telephoneResourceId") Long telephoneResourceId,
                                       @RequestParam("courseScheduleId") Long courseScheduleId){
        ModelAndView modelAndView = new ModelAndView("user/telephone/experience-edit");
        
        CourseSchedule courseSchedule = courseScheduleService.load(CourseSchedule.class, courseScheduleId);
        
        modelAndView.addObject("courseSchedule", courseSchedule);
        
        return modelAndView;
    }
    
    /**
     * cancel experience
     * @param telephoneResourceId
     * @param courseScheduleId
     * @return
     */
    @RequestMapping(value = "/{telephoneResourceId}/cancel-experience", method = RequestMethod.GET)
    public ModelAndView cancelExperience(@PathVariable("telephoneResourceId") Long telephoneResourceId,
                                         @RequestParam("courseScheduleId") Long courseScheduleId){
        ModelAndView modelAndView = new ModelAndView("user/telephone/experience-cancel");
        
        CourseSchedule courseSchedule = courseScheduleService.load(CourseSchedule.class, courseScheduleId);
        
        modelAndView.addObject("courseSchedule", courseSchedule);
        
        return modelAndView;
    }
}
